﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using tea.BL;
using tea.DB;
using tea.Models;
using Util;

namespace tea.Controllers
{
    [Authorize]
    public class UserController : Controller
    {
        [HttpGet]
        public ActionResult Main()
        {
            return Redirect(Url.BbsList(1));
        }

        public ActionResult ApplicationForm()
        {
            return View();
        }

        public ActionResult ApplicationFormList()
        {
            return View();
        }

        public ActionResult Logout()
        {
            BL사용자.로그아웃();
            return Main();
        }

        [HttpGet]
        public ActionResult MyPage()
        {
            return Edit(BL사용자.현재사용자.ID);
        }

        [HttpGet]
        [Authorize(Roles = BL사용자.ADMIN)]
        public ActionResult Edit(int id)
        {
            using (var db = new DBDataContext()) {
                var data = db.사용자.FirstOrDefault(p => p.ID == id);
                if (data == null) throw new Exception(Consts.작업실패);
                var 모델 = new UserEditModel {
                    ID = data.ID,
                    로그인ID = data.로그인ID,
                    이름 = data.이름,
                    이메일 = data.이메일,
                    역할 = BL사용자.사용자역할(data)
                };
                return View("Edit", 모델);
            }
        }

        [HttpPost]
        [Util.AjaxOnly]
        public ActionResult SaveMyInfo(UserEditModel 모델)
        {
            if (모델.ID != BL사용자.현재사용자.ID && BL사용자.IsAdmin() == false) return Json(Consts.Ajax권한없음);
            if (모델.로그인ID.Length < Consts.최소로그인ID크기) return Json(Consts.Ajax아이디크기오류);

            using (var db = new DBDataContext()) {
                var data = db.사용자.FirstOrDefault(p => p.ID == 모델.ID);
                if (data == null) return Json(Consts.Ajax작업실패);

                if (모델.로그인ID != data.로그인ID) {
                    if (db.사용자.Any(p => p.로그인ID == 모델.로그인ID)) return Json(Consts.Ajax아이디중복);
                }

                data.로그인ID = 모델.로그인ID;
                data.이름 = 모델.이름;
                data.이메일 = 모델.이메일;                
                db.SubmitChanges();
                if (data.ID == BL사용자.현재사용자.ID) BL사용자.현재사용자 = data;
                return Json(Consts.Ajax저장됨);
            }
        }

        [HttpPost]
        [Util.AjaxOnly]
        public ActionResult SavePassword(UserEditModel 모델)
        {
            if (모델.ID != BL사용자.현재사용자.ID && BL사용자.IsAdmin() == false) return Json(Consts.Ajax권한없음);
            if (모델.비밀번호1 == null || 모델.비밀번호2 == null) return Json(Consts.Ajax비밀번호불일치오류);
            if (모델.비밀번호1.Length < Consts.최소비밀번호크기) return Json(Consts.Ajax비밀번호크기오류);
            if (모델.비밀번호1 != 모델.비밀번호2) return Json(Consts.Ajax비밀번호불일치오류);

            using (var db = new DBDataContext()) {
                var data = db.사용자.FirstOrDefault(p => p.ID == 모델.ID);
                if (data == null) return Json(Consts.Ajax작업실패);

                var 암호화된비밀번호 = CryptographyHelper.CookieEncrypt(모델.비밀번호1);
                data.비밀번호 = 암호화된비밀번호;
                db.SubmitChanges();
                return Json(Consts.Ajax저장됨);
            }
        }

        [HttpPost]
        [Util.AjaxOnly]
        [Authorize(Roles = BL사용자.ADMIN)]
        public ActionResult SaveRole(UserEditModel 모델)
        {
            if (모델.ID != BL사용자.현재사용자.ID && BL사용자.IsAdmin() == false) return Json(Consts.Ajax권한없음);

            using (var db = new DBDataContext()) {
                var data = db.사용자.FirstOrDefault(p => p.ID == 모델.ID);
                if (data == null) return Json(Consts.Ajax작업실패);

                if (BL사용자.사용자역할(data) != 모델.역할) {
                    db.사용자_역할.DeleteAllOnSubmit(db.사용자_역할.Where(p => p.사용자ID == 모델.ID));
                    if (db.역할.Any(p => p.역할1 == 모델.역할))
                        db.사용자_역할.InsertOnSubmit(new DB.사용자_역할 { 사용자ID = 모델.ID, 역할 = 모델.역할 });
                    db.SubmitChanges();
                }
                return Json(Consts.Ajax저장됨);
            }
        }

        [HttpGet]
        [Authorize(Roles = BL사용자.ADMIN)]
        public ActionResult List(PaginationModel pagination)
        {
            string 키 = "UserList";
            ViewState.Load(키, pagination, PaginationModel.DEFAULT);

            using (var db = new DBDataContext()) {
                var list = db.사용자.Where(p => true);
                
                // 사용자 분류
                if (pagination.category != BL사용자.사용자분류_전체) list = list.Where(p => p.사용자_역할.Any(t => t.역할 == BL사용자.사용자분류[pagination.category.Value].Text));

                // 검색
                if (  pagination.srchType == BL게시판.검색_없음 || 
                     (Request.Url.Query.IndexOf("srchText") > 0 && string.IsNullOrWhiteSpace(Request.QueryString["srchText"]))) 
                {
                    pagination.srchType = BL사용자.검색_없음;
                    pagination.srchText = null;
                } else {
                    switch (pagination.srchType) {
                        case BL사용자.검색_이름: list = list.Where(p => p.이름.Contains(pagination.srchText)); break;
                        case BL사용자.검색_로그인ID: list = list.Where(p => p.로그인ID.Contains(pagination.srchText)); break;
                        default: Debug.Assert(false); break;
                    }
                }

                // 현재 페이지
                pagination.pageCount = (int)Math.Ceiling((double)list.Count() / (double)pagination.size);
                pagination.page = Math.Max(1, Math.Min(pagination.page.Value, pagination.pageCount.Value));
                pagination.url = Url.UserList(new PaginationModel { ID = pagination.ID, page = 989898 }).Replace("989898", "{0}");

                var 모델 = new UserListModel {
                    pagination = pagination,
                    사용자목록 = list.OrderBy(p => p.ID)
                                      .Skip((pagination.page.Value - 1) * pagination.size.Value)
                                      .Take(pagination.size.Value)
                                      .Select(p => new 사용자Model(p)).ToList()
                };
                ViewState.Save(키, pagination);
                return View(모델);
            }
        }
    }
}
